/*
 * SalesData.cpp
 *
 *  Created on: 2020年11月11日
 *      Author: san
 */

#include "Sales_data.h"
#include <string>

using std::string;

class Sales_data;



istream &read(istream &is, Sales_data &item)
{
	double price = 0;
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = price * item.units_sold;
	return is;
}

ostream &print(ostream &os, const Sales_data &item)
{
	os << "bookNo: " << item.isbn() << " " << "units_sold: " << item.getUnitSold() << " "
			<< "revenue: " << item.getRevenue() << " " << "price: " << item.avg_price();
	return os;
}

Sales_data::Sales_data(string s, unsigned cnt, double price): bookNo(s), units_sold(cnt), revenue(price)
{
	std::cout << "我是被委托人0" << std::endl;
}

Sales_data::~Sales_data() {
	// TODO Auto-generated destructor stub
}

std::istream &operator >>(std::istream &is, Sales_data &sd)
{
	// 重载流输入运算符
	double price;
	is >> sd.bookNo >> sd.units_sold >> price;
	if (is)
		sd.revenue = price * sd.units_sold;
	else
		sd = Sales_data();  // 当读取操作发生错误时，输入运算符应该负责从错误中恢复
	return is;
}

ostream &operator <<(ostream &os, const Sales_data &sd)
{
	// 重载流输出运算符
	os <<  "bookNo: " << sd.isbn() << " " << "units_sold: " << sd.getUnitSold() << " "
			<< "revenue: " << sd.getRevenue() << " " << "price: " << sd.avg_price();
	return os;
}

Sales_data &operator +(const Sales_data &lhs, const Sales_data &rhs)
{
	// 重载+运算符
	Sales_data ret(lhs);
	ret += rhs;
	return ret;
}

bool operator ==(const Sales_data &lhs, const Sales_data &rhs)
{
	if (lhs.isbn() == rhs.isbn() &&
			lhs.getUnitSold() == rhs.getUnitSold() && lhs.getRevenue() == rhs.getRevenue())
		return true;
	return false;
}

bool operator !=(const Sales_data &lhs, const Sales_data &rhs)
{
	return !(lhs == rhs);
}

Sales_data &Sales_data::operator +=(const Sales_data &rhs)
{
	if (this->isbn() != rhs.isbn())
		throw san::isbn_mismatch("wrong isbns");
	units_sold += rhs.units_sold;
	revenue = rhs.revenue;
	return *this;
}

double Sales_data::avg_price() const
{
	// :: 域作用符， 说明该函数被声明在Sales_data作用域内
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}

Sales_data &Sales_data::combine(const Sales_data &rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.revenue;
	return *this;
}

Sales_data Sales_data::add(const Sales_data &lhs, const Sales_data &rhs)
{
	Sales_data sum = lhs;
	sum.combine(rhs);
	return sum;
}

string Sales_data::toString() const
{
	string s = "";
//	s = s + this->isbn() + "," + static_cast<string>(this->getUnitSold()) + "," +
//			static_cast<string>(this->getRevenue()) + "," + static_cast<string>(this->avg_price());
	s = s + this->isbn() + "," + std::to_string(this->getUnitSold()) + "," + std::to_string(this->units_sold) +
			std::to_string(this->revenue) + "," + std::to_string(this->avg_price());
	return s;
}

std::vector<matches> findBook(const vector<vector<Sales_data>> &files, const string &book)
{
	std::vector<matches> ret;
	for (auto it = files.cbegin(); it != files.cend(); ++it)
	{
		// 查找具有相同的BookNo的范围
		auto found = std::equal_range(it->cbegin(), it->cend(), Sales_data(book),
				[](const Sales_data &lhs, const Sales_data &rhs){ return lhs.isbn() < rhs.isbn(); });
		if (found.first != found.second)  // 此书店销售了给定书籍
			// 记住此书店的索引及匹配的范围
			ret.push_back(std::make_tuple(it - files.cbegin(), found.first, found.second));
	}
	return ret;
}
